b4d8a61b02cee9fe15dd25a5085686b61574f3dc,applications/accounting/src/org/ofbiz/accounting/finaccount/FinAccountPaymentServices.java,FinAccountPaymentServices,finAccountPreAuth,#DispatchContext#Map#,61

Before Change


                    finAccount = FinAccountHelper.getFinAccountFromCode(finAccountCode, delegator);
                } catch (GenericEntityException e) {
                    Debug.logError(e, module);
                    return ServiceUtil.returnError("Unable to locate financial account from account code");
                }
            } else {
                return ServiceUtil.returnError("Both finAccountId and finAccountCode cannot be null; at least one is required");
            }
        }
        if (finAccount == null) {
            return ServiceUtil.returnError("Invalid financial account; cannot locate account");
        }

        String finAccountTypeId = finAccount.getString("finAccountTypeId");
        finAccountId = finAccount.getString("finAccountId");
        String statusId = finAccount.getString("statusId");

        try {
            // fin the store requires a pin number; validate the PIN with the code
            Map<String, Object> findProductStoreFinActSettingMap = UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "finAccountTypeId", finAccountTypeId);
            GenericValue finAccountSettings = delegator.findByPrimaryKeyCache("ProductStoreFinActSetting", findProductStoreFinActSettingMap);

            if (finAccountSettings == null) {
                Debug.logWarning("In finAccountPreAuth could not find ProductStoreFinActSetting record, values searched by: " + findProductStoreFinActSettingMap, module);
            }
            if (Debug.verboseOn()) Debug.logVerbose("In finAccountPreAuth finAccountSettings=" + finAccountSettings, module);

            BigDecimal minBalance = FinAccountHelper.ZERO;
            String allowAuthToNegative = "N";

            if (finAccountSettings != null) {
                allowAuthToNegative = finAccountSettings.getString("allowAuthToNegative");
                minBalance = finAccountSettings.getBigDecimal("minBalance");
                if (minBalance == null) {
                    minBalance = FinAccountHelper.ZERO;
                }

                // validate the PIN if the store requires it
                if ("Y".equals(finAccountSettings.getString("requirePinCode"))) {
                    if (!FinAccountHelper.validatePin(delegator, finAccountCode, finAccountPin)) {
                        Map<String, Object> result = ServiceUtil.returnSuccess();
                        result.put("authMessage", "Financial account PIN/CODE combination not found");
                        result.put("authResult", Boolean.FALSE);
                        result.put("processAmount", amount);
                        result.put("authFlag", "0");
                        result.put("authCode", "A");
                        result.put("authRefNum", "0");
                        Debug.logWarning("Unable to auth FinAccount: " + result, module);
                        return result;
                    }
                }
            }

            // check for expiration date
            if ((finAccount.getTimestamp("thruDate") != null) && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
                Map<String, Object> result = ServiceUtil.returnSuccess();
                result.put("authMessage", "Account has expired as of " + finAccount.getTimestamp("thruDate"));
                result.put("authResult", Boolean.FALSE);
                result.put("processAmount", amount);
                result.put("authFlag", "0");
                result.put("authCode", "A");
                result.put("authRefNum", "0");
                Debug.logWarning("Unable to auth FinAccount: " + result, module);
                return result;
            }

            // check for account being in bad standing somehow
            if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
                // refresh the finaccount
                finAccount.refresh();
                statusId = finAccount.getString("statusId");

                if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
                    Map<String, Object> result = ServiceUtil.returnSuccess();
                    if ("FNACT_NEGPENDREPL".equals(statusId)) {
                        result.put("authMessage", "Account is currently negative and pending replenishment");
                    } else if ("FNACT_MANFROZEN".equals(statusId)) {
                        result.put("authMessage", "Account is currently frozen");
                    } else if ("FNACT_CANCELLED".equals(statusId)) {
                        result.put("authMessage", "Account has been cancelled");
                    }
                    result.put("authResult", Boolean.FALSE);
                    result.put("processAmount", amount);
                    result.put("authFlag", "0");
                    result.put("authCode", "A");
                    result.put("authRefNum", "0");
                    Debug.logWarning("Unable to auth FinAccount: " + result, module);
                    return result;
                }
            }

            // check the amount to authorize against the available balance of fin account, which includes active authorizations as well as transactions
            BigDecimal availableBalance = finAccount.getBigDecimal("availableBalance");
            if (availableBalance == null) {
                availableBalance = FinAccountHelper.ZERO;
            } else {
                BigDecimal availableBalanceOriginal = availableBalance;
                availableBalance = availableBalance.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
                if (availableBalance.compareTo(availableBalanceOriginal) != 0) {
                    Debug.logWarning("In finAccountPreAuth for finAccountId [" + finAccountId + "] availableBalance [" + availableBalanceOriginal + "] was different after rounding [" + availableBalance + "]; it should never have made it into the database this way, so check whatever put it there.", module);
                }
            }


            Map<String, Object> result = ServiceUtil.returnSuccess();
            String authMessage = null;
            Boolean processResult;
            String refNum;

            // make sure to round and scale it to the same as availableBalance
            amount = amount.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);

            Debug.logInfo("Allow auth to negative: " + allowAuthToNegative + " :: available: " + availableBalance + " comp: " + minBalance + " = " + availableBalance.compareTo(minBalance) + " :: req: " + amount, module);
            // check the available balance to see if we can auth this tx
            if (("Y".equals(allowAuthToNegative) && availableBalance.compareTo(minBalance) > -1)
                    || (availableBalance.compareTo(amount) > -1)) {
                Timestamp thruDate;

                if (finAccountSettings != null && finAccountSettings.getLong("authValidDays") != null) {
                    thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), finAccountSettings.getLong("authValidDays"));
                } else {
                    thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), Long.valueOf(30)); // default 30 days for an auth
                }

                Map<String, Object> tmpResult = dispatcher.runSync("createFinAccountAuth", UtilMisc.<String, Object>toMap("finAccountId", finAccountId,
                        "amount", amount, "thruDate", thruDate, "userLogin", userLogin));

                if (ServiceUtil.isError(tmpResult)) {
                    return tmpResult;
                }
                refNum = (String) tmpResult.get("finAccountAuthId");
                processResult = Boolean.TRUE;

                // refresh the account
                finAccount.refresh();
            } else {
                Debug.logWarning("Attempted to authorize [" + amount + "] against a balance of only [" + availableBalance + "] for finAccountId [" + finAccountId + "]", module);
                refNum = "0"; // a refNum is always required from authorization
                authMessage = "Insufficient funds";
                processResult = Boolean.FALSE;
            }

            result.put("processAmount", amount);
            result.put("authMessage", authMessage);
            result.put("authResult", processResult);
            result.put("processAmount", amount);
            result.put("authFlag", "1");
            result.put("authCode", "A");
            result.put("authRefNum", refNum);
            Debug.logInfo("FinAccont Auth: " + result, module);

            return result;
        } catch (GenericEntityException ex) {
            Debug.logError(ex, "Cannot authorize financial account", module);
            return ServiceUtil.returnError("Cannot authorize financial account due to " + ex.getMessage());
        } catch (GenericServiceException ex) {
            Debug.logError(ex, "Cannot authorize gift certificate", module);
            return ServiceUtil.returnError("Cannot authorize financial account due to " + ex.getMessage());
        }
    }

After Change


                    finAccount = FinAccountHelper.getFinAccountFromCode(finAccountCode, delegator);
                } catch (GenericEntityException e) {
                    Debug.logError(e, module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                            "AccountingFinAccountCannotLocateItFromAccountCode", locale));
                }
            } else {
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                        "AccountingFinAccountIdAndFinAccountCodeAreNull", locale));
            }
        }
        if (finAccount == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "AccountingFinAccountIdInvalid", locale));
        }

        String finAccountTypeId = finAccount.getString("finAccountTypeId");
        finAccountId = finAccount.getString("finAccountId");
        String statusId = finAccount.getString("statusId");

        try {
            // fin the store requires a pin number; validate the PIN with the code
            Map<String, Object> findProductStoreFinActSettingMap = UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "finAccountTypeId", finAccountTypeId);
            GenericValue finAccountSettings = delegator.findByPrimaryKeyCache("ProductStoreFinActSetting", findProductStoreFinActSettingMap);

            if (finAccountSettings == null) {
                Debug.logWarning("In finAccountPreAuth could not find ProductStoreFinActSetting record, values searched by: " + findProductStoreFinActSettingMap, module);
            }
            if (Debug.verboseOn()) Debug.logVerbose("In finAccountPreAuth finAccountSettings=" + finAccountSettings, module);

            BigDecimal minBalance = FinAccountHelper.ZERO;
            String allowAuthToNegative = "N";

            if (finAccountSettings != null) {
                allowAuthToNegative = finAccountSettings.getString("allowAuthToNegative");
                minBalance = finAccountSettings.getBigDecimal("minBalance");
                if (minBalance == null) {
                    minBalance = FinAccountHelper.ZERO;
                }

                // validate the PIN if the store requires it
                if ("Y".equals(finAccountSettings.getString("requirePinCode"))) {
                    if (!FinAccountHelper.validatePin(delegator, finAccountCode, finAccountPin)) {
                        Map<String, Object> result = ServiceUtil.returnSuccess();
                        result.put("authMessage", UtilProperties.getMessage(resourceError, 
                                "AccountingFinAccountPinCodeCombinatorNotFound", locale));
                        result.put("authResult", Boolean.FALSE);
                        result.put("processAmount", amount);
                        result.put("authFlag", "0");
                        result.put("authCode", "A");
                        result.put("authRefNum", "0");
                        Debug.logWarning("Unable to auth FinAccount: " + result, module);
                        return result;
                    }
                }
            }

            // check for expiration date
            if ((finAccount.getTimestamp("thruDate") != null) && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
                Map<String, Object> result = ServiceUtil.returnSuccess();
                result.put("authMessage", UtilProperties.getMessage(resourceError, 
                        "AccountingFinAccountExpired", 
                        UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")), locale));
                result.put("authResult", Boolean.FALSE);
                result.put("processAmount", amount);
                result.put("authFlag", "0");
                result.put("authCode", "A");
                result.put("authRefNum", "0");
                Debug.logWarning("Unable to auth FinAccount: " + result, module);
                return result;
            }

            // check for account being in bad standing somehow
            if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
                // refresh the finaccount
                finAccount.refresh();
                statusId = finAccount.getString("statusId");

                if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
                    Map<String, Object> result = ServiceUtil.returnSuccess();
                    if ("FNACT_NEGPENDREPL".equals(statusId)) {
                        result.put("authMessage", UtilProperties.getMessage(resourceError, 
                                "AccountingFinAccountNegative", locale));
                    } else if ("FNACT_MANFROZEN".equals(statusId)) {
                        result.put("authMessage", UtilProperties.getMessage(resourceError, 
                                "AccountingFinAccountFrozen", locale));
                    } else if ("FNACT_CANCELLED".equals(statusId)) {
                        result.put("authMessage", UtilProperties.getMessage(resourceError, 
                                "AccountingFinAccountCancelled", locale));
                    }
                    result.put("authResult", Boolean.FALSE);
                    result.put("processAmount", amount);
                    result.put("authFlag", "0");
                    result.put("authCode", "A");
                    result.put("authRefNum", "0");
                    Debug.logWarning("Unable to auth FinAccount: " + result, module);
                    return result;
                }
            }

            // check the amount to authorize against the available balance of fin account, which includes active authorizations as well as transactions
            BigDecimal availableBalance = finAccount.getBigDecimal("availableBalance");
            if (availableBalance == null) {
                availableBalance = FinAccountHelper.ZERO;
            } else {
                BigDecimal availableBalanceOriginal = availableBalance;
                availableBalance = availableBalance.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
                if (availableBalance.compareTo(availableBalanceOriginal) != 0) {
                    Debug.logWarning("In finAccountPreAuth for finAccountId [" + finAccountId + "] availableBalance [" + availableBalanceOriginal + "] was different after rounding [" + availableBalance + "]; it should never have made it into the database this way, so check whatever put it there.", module);
                }
            }


            Map<String, Object> result = ServiceUtil.returnSuccess();
            String authMessage = null;
            Boolean processResult;
            String refNum;

            // make sure to round and scale it to the same as availableBalance
            amount = amount.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);

            Debug.logInfo("Allow auth to negative: " + allowAuthToNegative + " :: available: " + availableBalance + " comp: " + minBalance + " = " + availableBalance.compareTo(minBalance) + " :: req: " + amount, module);
            // check the available balance to see if we can auth this tx
            if (("Y".equals(allowAuthToNegative) && availableBalance.compareTo(minBalance) > -1)
                    || (availableBalance.compareTo(amount) > -1)) {
                Timestamp thruDate;

                if (finAccountSettings != null && finAccountSettings.getLong("authValidDays") != null) {
                    thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), finAccountSettings.getLong("authValidDays"));
                } else {
                    thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), Long.valueOf(30)); // default 30 days for an auth
                }

                Map<String, Object> tmpResult = dispatcher.runSync("createFinAccountAuth", UtilMisc.<String, Object>toMap("finAccountId", finAccountId,
                        "amount", amount, "thruDate", thruDate, "userLogin", userLogin));

                if (ServiceUtil.isError(tmpResult)) {
                    return tmpResult;
                }
                refNum = (String) tmpResult.get("finAccountAuthId");
                processResult = Boolean.TRUE;

                // refresh the account
                finAccount.refresh();
            } else {
                Debug.logWarning("Attempted to authorize [" + amount + "] against a balance of only [" + availableBalance + "] for finAccountId [" + finAccountId + "]", module);
                refNum = "0"; // a refNum is always required from authorization
                authMessage = "Insufficient funds";
                processResult = Boolean.FALSE;
            }

            result.put("processAmount", amount);
            result.put("authMessage", authMessage);
            result.put("authResult", processResult);
            result.put("processAmount", amount);
            result.put("authFlag", "1");
            result.put("authCode", "A");
            result.put("authRefNum", refNum);
            Debug.logInfo("FinAccont Auth: " + result, module);

            return result;
        } catch (GenericEntityException ex) {
            Debug.logError(ex, "Cannot authorize financial account", module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "AccountingFinAccountCannotBeAuthorized", 
                    UtilMisc.toMap("errorString", ex.getMessage()), locale));
        } catch (GenericServiceException ex) {
            Debug.logError(ex, "Cannot authorize financial account", module);
         return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, 
                    "AccountingFinAccountCannotBeAuthorized", 
                    UtilMisc.toMap("errorString", ex.getMessage()), locale));
        }
    }